/*
 * Copyright (c) 2021 Zsj. All rights reserved.
 */

package com.jzz.crawlerweb.handler.generator;

import java.awt.image.BufferedImage;

/**
 * 图片波纹效果
 */
public class WaveEffect {
    public static final double PI = 3.1415926;

    // water wave....
    public static BufferedImage waveImage(BufferedImage image, int span, int peak, int beta, int offset) {
        BufferedImage bimg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);

        int x_center = image.getWidth() / 2;
        int y_center = image.getHeight() / 2;

        double v = -Math.cos(beta * PI / 180.0);
        double distance, he;
        int y_offset;

        for (int y = 0; y < image.getHeight(); y++) {
            for (int x = 0; x < image.getWidth(); x++) {
                distance = Math.sqrt((x - x_center) * (x - x_center) + (y - y_center) * (y - y_center) / (v * v));
                he = Math.cos((distance + offset) * PI / span) * peak;
                y_offset = (int) (he * v);
                for (int i = y_offset - 2; i <= y_offset + 2; i++) {
                    try {
                        bimg.setRGB(x, y - i, image.getRGB(x, y));
                    } catch (Exception e) {

                    }
                }
            }
        }

        return bimg;
    }

    // ripple ....
    public static BufferedImage rippleImage(BufferedImage image, int span, int peak, int off) {
        BufferedImage bimg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);

        int x_center = image.getWidth() / 2;
        int y_center = image.getHeight() / 2;

        boolean isWidth = x_center > y_center;
        int r = isWidth ? x_center : y_center;

        double distance, d2;
        double offset;
        int x_offset;
        int y_offset;
        int x1, y1;
        double scale = x_center / (double) y_center;

        for (int y = 0; y < image.getHeight(); y++) {
            for (int x = 0; x < image.getWidth(); x++) {
                x1 = x - x_center;
                y1 = y - y_center;
                d2 = Math.sqrt(x1 * x1 + y1 * y1 * scale * scale) + off;

                distance = Math.sqrt(x1 * x1 + y1 * y1);
                offset = Math.sin(d2 * PI / span) * span * (1 - distance / r);

                if (x1 == 0 && y1 <= 0) {
                    x_offset = -(int) (offset * Math.cos(PI / 2.0));
                    y_offset = -(int) (offset * Math.sin(PI / 2.0));
                } else if (x1 == 0 && y1 > 0) {
                    x_offset = -(int) (offset * Math.cos(PI / 2.0));
                    y_offset = (int) (offset * Math.sin(PI / 2.0));
                } else if (x > x_center) {
                    x_offset = (int) (offset * Math.cos(Math.atan(y1 / (double) x1)));
                    y_offset = (int) (offset * Math.sin(Math.atan(y1 / (double) x1)));
                } else {
                    x_offset = -(int) (offset * Math.cos(Math.atan(y1 / (double) x1)));
                    y_offset = -(int) (offset * Math.sin(Math.atan(y1 / (double) x1)));
                }

                try {
                    bimg.setRGB(x, y, image.getRGB(x - x_offset, y - y_offset));
                } catch (Exception e) {

                }
            }
        }

        return bimg;
    }
}